package com.example.yin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.yin.common.R;
import com.example.yin.constant.Constants;
import com.example.yin.mapper.ConsumerMapper;
import com.example.yin.model.domain.Consumer;
import com.example.yin.model.request.ConsumerRequest;
import com.example.yin.service.ConsumerService;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;

import static com.example.yin.constant.Constants.SALT;

@Service
@CacheConfig(cacheNames = "userCache")
public class ConsumerServiceImpl extends ServiceImpl<ConsumerMapper, Consumer>
        implements ConsumerService {

    @Autowired
    private ConsumerMapper consumerMapper;


    /**
     * 新增用户
     */
    @CachePut(key = "#result.data.id")
    @Override
    public R addUser(ConsumerRequest registryRequest) {
        // 检查用户名是否已注册
        if (this.existUser(registryRequest.getUsername())) {
            return R.warning("用户名已注册");
        }
        Consumer consumer = new Consumer();
        BeanUtils.copyProperties(registryRequest, consumer);
        //MD5加密
        String password = DigestUtils.md5DigestAsHex((SALT + registryRequest.getPassword()).getBytes(StandardCharsets.UTF_8));
        consumer.setPassword(password);
        // 处理手机号和邮箱为空的情况
        if (StringUtils.isBlank(consumer.getPhoneNum())) {
            consumer.setPhoneNum(null);
        }
        if ("".equals(consumer.getEmail())) {
            consumer.setEmail(null);
        }
        // 设置默认头像路径、创建时间和更新时间
        consumer.setAvator("img/avatorImages/user.jpg");
        consumer.setCreateTime(new Date());
        consumer.setUpdateTime(new Date());
        try {
            // 执行数据库插入操作，并判断是否插入成功
            if (consumerMapper.insert(consumer) > 0) {
                return R.success("注册成功", consumer);
            } else {
                return R.error("注册失败");
            }
        } catch (DuplicateKeyException e) {
            return R.fatal(e.getMessage());
        }
    }

    @Override
    public R updateUserMsg(ConsumerRequest updateRequest) {
        Consumer consumer = new Consumer();
        BeanUtils.copyProperties(updateRequest, consumer);
        // 设置更新时间为当前时间
        consumer.setUpdateTime(new Date());
//        执行根据ID修改操作,判断修改成功与否
        if (consumerMapper.updateById(consumer) > 0) {
            return R.success("修改成功");
        } else {
            return R.error("修改失败");
        }
    }

    @Override
    public R updatePassword(ConsumerRequest updatePasswordRequest) {
        // 验证旧密码是否正确
        if (!this.verityPasswd(updatePasswordRequest.getUsername(), updatePasswordRequest.getOldPassword())) {
            return R.error("密码输入错误");
        }

        Consumer consumer = new Consumer();
        // 设置Consumer对象的ID
        consumer.setId(updatePasswordRequest.getId());
        // 对新密码进行MD5加密
        String secretPassword = DigestUtils.md5DigestAsHex((SALT + updatePasswordRequest.getPassword()).getBytes(StandardCharsets.UTF_8));
        // 设置Consumer对象的密码为加密后的新密码
        consumer.setPassword(secretPassword);
        // 执行数据库更新操作，并判断是否更新成功
        if (consumerMapper.updateById(consumer) > 0) {
            return R.success("密码修改成功");
        } else {
            return R.error("密码修改失败");
        }
    }

    @Override
    public R updateUserAvator(MultipartFile avatorFile, int id) {
        String fileName = System.currentTimeMillis() + avatorFile.getOriginalFilename();
        // 定义文件保存路径，根据系统获取对应的文件分隔符
        String filePath = Constants.PROJECT_PATH + System.getProperty("file.separator") + "img" + System.getProperty("file.separator") + "avatorImages";
        // 创建目录文件对象
        File file = new File(filePath);
        // 如果目录文件不存在且创建失败，则返回创建文件失败的致命错误响应
        if (!file.exists() && !file.mkdir()) {
            return R.fatal("创建文件失败");
        }
        File dest = new File(filePath + System.getProperty("file.separator") + fileName);
        // 定义图片路径
        String imgPath = "/img/avatorImages/" + fileName;
        try {
            // 将上传的文件保存到目标文件中
            avatorFile.transferTo(dest);
        } catch (IOException e) {
            return R.fatal("上传失败" + e.getMessage());
        }
        Consumer consumer = new Consumer();
        // 设置Consumer对象的ID
        consumer.setId(id);
        consumer.setAvator(imgPath);
        // 执行数据库更新操作，并判断是否更新成功
        if (consumerMapper.updateById(consumer) > 0) {
            // 如果更新成功，则返回上传成功的响应，其中包含上传成功的图片路径
            return R.success("上传成功", imgPath);
        } else {
            // 如果更新失败，则返回上传失败的错误响应
            return R.error("上传失败");
        }
    }

    @Override
    public boolean existUser(String username) {
        QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
        // 设置查询条件：用户名等于给定的用户名
        queryWrapper.eq("username", username);
        // 执行数据库查询操作，并判断是否存在满足条件的记录
        return consumerMapper.selectCount(queryWrapper) > 0;
    }

    @Override
    public boolean verityPasswd(String username, String password) {
        QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        // 对输入的密码进行MD5加密
        String secretPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes(StandardCharsets.UTF_8));
        // 设置查询条件：密码等于加密后的密码
        queryWrapper.eq("password", secretPassword);
        // 执行数据库查询操作，并判断是否存在满足条件的记录
        return consumerMapper.selectCount(queryWrapper) > 0;
    }

    // 删除用户
    @Override
    @CacheEvict(key = "#id")
    public R deleteUser(Integer id) {
        // 执行数据库删除操作，并判断是否删除成功
        if (consumerMapper.deleteById(id) > 0) {
            return R.success("删除成功");
        } else {
            return R.error("删除失败");
        }
    }

    @Override
    // 执行数据库查询操作，获取所有用户信息
    public R allUser() {
        return R.success(null, consumerMapper.selectList(null));
    }

    @Override
    @Cacheable(key = "#id")
    public R userOfId(Integer id) {
        QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        System.out.println("用户查询没有走缓存");
        // 执行数据库查询操作，根据ID查询用户信息，并返回查询结果
        return R.success(null, consumerMapper.selectList(queryWrapper));
    }

    @Override
    public R loginStatus(ConsumerRequest loginRequest, HttpSession session, HttpServletRequest request) {
// 获取登录请求的用户名和密码
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();

// 验证用户名和密码是否匹配
        if (this.verityPasswd(username, password)) {
            // 如果匹配，则将用户名保存到Session中
            session.setAttribute("username", username);
            Consumer consumer = new Consumer();
            consumer.setUsername(username);
            // 执行数据库查询操作，根据用户名查询用户信息，并返回查询结果
            return R.success("登录成功", consumerMapper.selectList(new QueryWrapper<>(consumer)));
        } else {
            return R.error("用户名或密码错误");
        }
    }

    public boolean loginInfo(HttpServletRequest request) {

        // 获取请求头中的User-Agent信息
        String agentStr = request.getHeader("user-agent");
        System.out.println(agentStr);
        // 解析User-Agent字符串，获取浏览器、浏览器版本和操作系统信息
        UserAgent agent = UserAgent.parseUserAgentString(agentStr);
        // 获取浏览器信息
        Browser browser = agent.getBrowser();
        System.out.println("类型：" + browser.getBrowserType() +
                "\n名称：" + browser.getName() +
                "\n厂商：" + browser.getManufacturer() +
                "\n产品系列：" + browser.getGroup() +
                "\n引擎：" + browser.getRenderingEngine());

        // 获取浏览器版本信息
        Version version = agent.getBrowserVersion();
        System.out.println("========================");
        System.out.println("主版本：" + version.getMajorVersion() +
                "\n小版本：" + version.getMinorVersion() +
                "\n完整版本：" + version.getVersion());
        // 获取操作系统信息
        System.out.println("========================");
        OperatingSystem os = agent.getOperatingSystem();
        System.out.println("名称：" + os.getName() +
                "\n设备类型：" + os.getDeviceType() +
                "\n产品系列：" + os.getGroup() +
                "\n生成厂商：" + os.getManufacturer());
        return true;
    }
}
